#include "RandomNumberGenerator.h"
#include "time.h"
#include "math.h"
#include "Constants.h"


RandomNumberGenerator::RandomNumberGenerator()
{

}

int RandomNumberGenerator::nextInt(int max) {
    float a = getUniform();
    a = static_cast<int>(a * max);
    return a;
}
float RandomNumberGenerator::nextFloat(float max) {
    float a = getUniform() * max;
    return a;
}
void RandomNumberGenerator::setSeedFromSystemTime() {
    m_w = 521288629;
    m_z = 362436069;
    time_t seconds;
    seconds = time (NULL);
    setSeed((unsigned int)(seconds >> 16), (unsigned int)(seconds % 4294967296));
}
void RandomNumberGenerator::setSeed(unsigned int u, unsigned int v) {
    if (u != 0) m_w = u;
    if (v != 0) m_z = v;
}
// Produce a uniform random sample from the open interval (0, 1).
// The method will not return either end point.
double RandomNumberGenerator::getUniform() {
    // 0 <= u < 2^32
    unsigned int u = getUint();
    // The magic number below is 1/(2^32 + 2).
    // The result is strictly between 0 and 1.
    return (u + 1.0) * 2.328306435454494e-10;
}
// This is the heart of the generator.
// It uses George Marsaglia's MWC algorithm to produce an unsigned integer.
// See http://www.bobwheeler.com/statistics/Password/MarsagliaPost.txt
unsigned int RandomNumberGenerator::getUint() {
    m_z = 36969 * (m_z & 65535) + (m_z >> 16);
    m_w = 18000 * (m_w & 65535) + (m_w >> 16);
    return (m_z << 16) + m_w;
}
// Get normal (Gaussian) random sample with mean 0 and standard deviation 1
double RandomNumberGenerator::getNormal() {
    // Use Box-Muller algorithm
    double u1 = getUniform();
    double u2 = getUniform();
    //double r = Math.Sqrt( -2.0*Math.Log(u1) );
    double r = sqrt(-2.0*log(u1));
    double theta = 2.0*PI*u2;
    return r*sin(theta);
}
